#include "../h/iThreadMgr.h"
#include "../h/iLogger.h"
#include "iIOThread.h"
#include "iTimerThread.h"
#include "iIOR.h"

#define FUNC(x) iFUNC(MOD_UTIL,x)

#if defined(__LINUX__)
#include <sys/syscall.h>
pid_t gettid()
{
    return syscall(SYS_gettid);
}
#endif

std::vector< std::list<iThread*> > iThreadMgr::s_threads(MAX_THREAD_TYPE);
long iThreadMgr::get_process_id()
{
#if defined(__WIN__)
	return ::GetCurrentProcessId();
#elif defined(__LINUX__)
	return getpid();
#endif
}
long iThreadMgr::get_thread_id()
{
#if defined(__WIN__)
	return GetCurrentThreadId();
#elif defined(__LINUX__)
	return gettid();
#endif
}
iThread* iThreadMgr::spawn_io(bool def)
{
    FUNC("iThreadMgr::spawn_io");

	std::list<iThread*> & io_thd = s_threads[IO_THREAD];
	if(io_thd.empty())
		io_thd.push_back(NULL);

	iThread*& def_io = io_thd.front();
	if(def && def_io==NULL)
	{
		def_io = new iIOThread();
		def_io->start();
	}

	if(def)
		return def_io;
	else
	{
		iThread* thd = new iIOThread();
		thd->start();
		io_thd.push_back(thd);
		return thd;
	}
}
iThread* iThreadMgr::spawn_timer()
{
    FUNC("iThreadMgr::spawn_timer");

	std::list<iThread*> & tm_thd = s_threads[TIMER_THREAD];
	if(tm_thd.empty())
		tm_thd.push_back(NULL);

	iThread*& thd = tm_thd.front();
	if(NULL == thd)
	{
		thd = new iTimerThread();
		thd->start();
	}

	return thd;
}
iThread* iThreadMgr::spawn_this()
{
    if(iThread::tls_thread == NULL)
    {
        class iDummyMsgThread : public iMsgThread
        {
        public:
            inline iDummyMsgThread()
            {
                m_id = get_thread_id();
            }
            virtual int run()
            {
                iMsg* msg = get_message();
                if(NULL == msg)
                {
                    return 0;
                }
                else
                {
                    msg->process();
                    return 1;
                }
            }
        };
        iThread* thd = new iDummyMsgThread();
        iThread::tls_thread = thd;
    }

	return iThread::tls_thread;
}

iThread* iThreadMgr::this_thread()
{
	long tid = get_thread_id();
	for(std::vector< std::list<iThread*> >::iterator iter=s_threads.begin(); iter!=s_threads.end(); ++iter)
	{
		for(std::list<iThread*>::iterator ithr=iter->begin(); ithr!=iter->end(); ++ithr)
		{
			if((*ithr)->get_id() == tid)
				return *ithr;
		}
	}

	return NULL;
}
